package com.sugree.twitter.views;

import java.util.Vector;
import java.util.Enumeration;
import javax.microedition.lcdui.Choice;
import javax.microedition.lcdui.List;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Displayable;

import com.substanceofcode.twitter.model.Status;
import com.substanceofcode.utils.Log;

import com.sugree.twitter.tasks.RequestTimelineTask;
import com.sugree.twitter.TwitterController;
import com.sugree.utils.DateUtil;

public class TimelineScreen extends List implements CommandListener {
	private TwitterController controller;
	private Command replyCommand;
	private Command updateCommand;
	private Command friendsTimelineCommand;
	private Command publicTimelineCommand;
	private Command userTimelineCommand;
	private Command repliesTimelineCommand;
	private Command directTimelineCommand;
	private Command favoritesTimelineCommand;
	private Command setupCommand;
	private Command logCommand;
	private Command aboutCommand;
	private Command minimizeCommand;
	private Command exitCommand;

	private Vector statuses;
	private long selectedStatus;
	private int length;

	public TimelineScreen(TwitterController controller) {
		super("jibjib", Choice.IMPLICIT);
		this.controller = controller;

		selectedStatus = 0;
		statuses = new Vector();

		updateCommand = new Command("Tweet", Command.SCREEN, 1);
		addCommand(updateCommand);
		replyCommand = new Command("Reply", Command.ITEM, 2);
		addCommand(replyCommand);

		friendsTimelineCommand = new Command("Friends Timeline", Command.SCREEN, 3);
		addCommand(friendsTimelineCommand);
		repliesTimelineCommand = new Command("Replies Timeline", Command.SCREEN, 4);
		addCommand(repliesTimelineCommand);
		directTimelineCommand = new Command("Direct messages", Command.SCREEN, 5);
		addCommand(directTimelineCommand);
		favoritesTimelineCommand = new Command("Favorites", Command.SCREEN, 6);
		addCommand(favoritesTimelineCommand);
		userTimelineCommand = new Command("User Timeline", Command.SCREEN, 7);
		addCommand(userTimelineCommand);
		publicTimelineCommand = new Command("Public Timeline", Command.SCREEN, 8);
		addCommand(publicTimelineCommand);

		setupCommand = new Command("Setup", Command.SCREEN, 16);
		addCommand(setupCommand);
		logCommand = new Command("Log", Command.SCREEN, 17);
		addCommand(logCommand);
		aboutCommand = new Command("About", Command.SCREEN, 18);
		addCommand(aboutCommand);
		minimizeCommand = new Command("Minimize", Command.EXIT, 19);
		addCommand(minimizeCommand);
		exitCommand = new Command("Exit", Command.EXIT, 20);
		addCommand(exitCommand);

		setCommandListener(this);
	}

	private void saveSelected() {
		int index = getSelectedIndex();

		if (index >= 0 && index < statuses.size()) {
			selectedStatus = ((Status)statuses.elementAt(index)).getId();
		}
	}

	private void restoreSelected() {
		int lastIndex = findStatus(selectedStatus);
		if (lastIndex < 0) {
			lastIndex = statuses.size()-1;
		}
		if (lastIndex >= 0 && lastIndex < statuses.size()) {
			setSelectedIndex(lastIndex, true);
		}
	}

	public void setLength(int length) {
		this.length = length;
	}

	public void clearTimeline() {
		statuses.removeAllElements();
		removeAll();
	}

	public void addTimeline(Vector timeline) {
		saveSelected();
		for(int i=0; i<timeline.size(); i++) {
			if (i < statuses.size()) {
				statuses.insertElementAt(timeline.elementAt(i), i);
			} else {
				statuses.addElement(timeline.elementAt(i));
			}
		}
		if (statuses.size() > length) {
			statuses.setSize(length);
			statuses.trimToSize();
		}
		updateTimeline();
		restoreSelected();
	}

	public void update(Status status) {
		int index = findStatus(status.getId());
		if (index >= 0) {
			statuses.setElementAt(status, index);
			saveSelected();
			updateTimeline();
			restoreSelected();
		}
	}

	public String getLastDate() {
		if (statuses != null && statuses.size() > 0) {
			Status status = (Status)statuses.elementAt(0);
			return DateUtil.formatHTTPDate(status.getDate());
		}
		return "";
	}

	public String getLastId() {
		if (statuses != null && statuses.size() > 0) {
			Status status = (Status)statuses.elementAt(0);
			return String.valueOf(status.getId());
		}
		return "";
	}

	public Vector getTimeline() {
		return statuses;
	}

	private int findStatus(long status) {
		for(int i=0; i<statuses.size(); i++) {
			if (((Status)statuses.elementAt(i)).getId() == status) {
				return i;
			}
		}
		return -1;
	}

	public void removeAll() {
		while (size() > 0) {
			delete(0);
		}
	}

	private void updateTimeline() {
		removeAll();

		Enumeration statusEnum = statuses.elements();
		while(statusEnum.hasMoreElements()) {
			Status status = (Status)statusEnum.nextElement();
			append(status.getScreenName()+": "+status.getText(), null);
		}
	}

	public void commandAction(Command cmd, Displayable display) {
		int index = getSelectedIndex();
		if (cmd == List.SELECT_COMMAND && index >= 0) {
			Status status = (Status)statuses.elementAt(index);
			controller.showStatus(status);
		} if (cmd == replyCommand && index >= 0) {
			Status status = (Status)statuses.elementAt(index);
			controller.showUpdate("@"+status.getScreenName()+" ");
		} else if (cmd == updateCommand) {
			controller.showUpdate();
		} else if (cmd == friendsTimelineCommand) {
			controller.fetchTimeline(RequestTimelineTask.FEED_FRIENDS);
		} else if (cmd == publicTimelineCommand) {
			controller.fetchTimeline(RequestTimelineTask.FEED_PUBLIC);
		} else if (cmd == userTimelineCommand) {
			controller.fetchTimeline(RequestTimelineTask.FEED_USER);
		} else if (cmd == repliesTimelineCommand) {
			controller.fetchTimeline(RequestTimelineTask.FEED_REPLIES);
		} else if (cmd == directTimelineCommand) {
			controller.fetchTimeline(RequestTimelineTask.FEED_DIRECT);
		} else if (cmd == favoritesTimelineCommand) {
			controller.fetchTimeline(RequestTimelineTask.FEED_FAVORITES);
		} else if (cmd == setupCommand) {
			controller.showSetup();
		} else if (cmd == logCommand) {
			controller.showLog();
		} else if (cmd == aboutCommand) {
			controller.showAbout();
		} else if (cmd == minimizeCommand) {
			controller.minimize();
		} else if (cmd == exitCommand) {
			controller.exit();
		}
	}
}
